﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.Reflection;
using System.Text;
using System.Xml;
using NOS.Common.ThreadSafe;
using System.Configuration;
using System.Xml.Serialization;
using System.IO;

namespace NOS.Reflection.NAC
{
    public class NAC
    {
        #region . Variables and Fields .
        
        // Variable for singleton instance of NAC
        private static NAC Instance = null;

        // Variable for Assembly cache
        private SafeHashTable AssembliesLocation = null;
        private SafeHashTable AssembliesCache = null;

        #endregion

        #region . Contructos .

        private NAC()
        {
            AssembliesLocation = new SafeHashTable();
            AssembliesCache = new SafeHashTable();
        }

        #endregion

        #region . Private Methods .

        private object[] MakeArguments(NameValueCollection Arguments)
        {
            object[] NewArguments = null;

            //foreach(Arguments.

            return NewArguments;
        }

        private MethodInfo FindMethod(Type Class, string MethodName, NameValueCollection Arguments, out object[] OrderedArguments)
        {
            MethodInfo SelMethod = null;
            object[] NewArgs = null;
            foreach (MethodInfo CurrentMethod in Class.GetMethods())
            {
                if (CurrentMethod.Name == MethodName && CurrentMethod.IsPublic)
                {
                    SelMethod = CurrentMethod;
                    break;
                }
            }
            OrderedArguments = NewArgs;
            return SelMethod;
        }

        #endregion

        #region . Public Methods .

        public Type GetClass(string fullnameClass)
        {
            Hashtable AssembliesLocation_tmp = AssembliesLocation.GetShared();
            Hashtable AssembliesCache_tmp = AssembliesCache.GetShared();
            bool UseGAC = bool.Parse(ConfigurationManager.AppSettings["UseGAC"]);
            try
            {
                if (AssembliesLocation_tmp[fullnameClass] != null)
                {


                }
                else if (UseGAC)
                {

                }
            }
            finally
            {
                AssembliesLocation.ReleaseShared();
                AssembliesCache.ReleaseShared();
            }

            return null;
        }

        public void LoadAssemblies()
        {
            Hashtable AssembliesLocation_tmp =  AssembliesLocation.GetExclusive();
            Hashtable AssembliesCache_tmp = AssembliesCache.GetExclusive();
            

            AssembliesLocation_tmp.Clear();
            AssembliesCache_tmp.Clear();
            
            string AssembliesPath = "";

            try
            {
                AssembliesPath = ConfigurationManager.AppSettings["NAC"].ToString();
                AssembliesPath += ";"+ConfigurationManager.AppSettings["Assembliespath"].ToString();
            }catch{}

            try
            {
                foreach (string Currentdir in AssembliesPath.Split(';'))
                {
                    foreach (string CurrentAssembly in Directory.GetFiles(Currentdir, "*.dll"))
                    {
                        Assembly LoadedAssembly = Assembly.LoadFrom(CurrentAssembly);
                        if (LoadedAssembly != null)
                        {
                            AssembliesCache_tmp.Add(CurrentAssembly, LoadedAssembly);

                            foreach (Type CurrentType in LoadedAssembly.GetTypes())
                            {
                                 AssembliesCache_tmp.Add(CurrentType.Namespace+"."+CurrentType.Name,CurrentAssembly);
                            }
                        }
                    }
                }
            } 
            finally
            {
                AssembliesLocation.ReleaseExclusive();
                AssembliesCache.ReleaseExclusive();
            }
        }

        /* Method to get the singleton instance of NAC */
        public static NAC Getinstance()
        {
            if (Instance == null)
            {
                Instance = new NAC();
            }
            return Instance;
        }

        #endregion

    }
}

